package com.example.dingdong.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.dingdong.common.Result;
import com.example.dingdong.controller.MinioUploadController;
import com.example.dingdong.mapper.SongMapper;
import com.example.dingdong.model.domain.Song;
import com.example.dingdong.model.request.SongRequest;
import com.example.dingdong.service.SongService;
import io.minio.MinioClient;
import io.minio.RemoveObjectArgs;
import io.minio.errors.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.List;

@Service
public class SongServiceImpl extends ServiceImpl<SongMapper, Song> implements SongService {

   @Autowired
   private SongMapper songMapper; // 注入歌曲映射器

   @Value("${minio.bucket-name}")
   private String bucketName; // MinIO存储桶名称

   @Autowired
   MinioClient minioClient;

   // 获取所有歌曲
   @Override
   public Result allSong() {
      QueryWrapper<Song> queryWrapper = new QueryWrapper<>();
      //根据name字段降序显示
      queryWrapper.orderByDesc("name");
      return Result.success(null, songMapper.selectList(null));
   }

   @Override
   public Result addSong(SongRequest addSongRequest, MultipartFile lrcfile, MultipartFile mpfile) {
      Song song = new Song();
      BeanUtils.copyProperties(addSongRequest, song);
      String pic = "/img/singerPic/default.jpg";
      String fileName = mpfile.getOriginalFilename();
      String s = MinioUploadController.uploadFile(mpfile);
      String storeUrlPath = "/" + bucketName + "/" + fileName;
      song.setCreateTime(new Date());
      song.setUpdateTime(new Date());
      song.setPic(pic);
      song.setUrl(storeUrlPath);

      if (lrcfile != null && (song.getLyric().equals("[00:00:00]暂无歌词"))) {
         byte[] fileContent = new byte[0];
         try {
            fileContent = lrcfile.getBytes();
            String content = new String(fileContent, "GB2312");
            song.setLyric(content);
         } catch (IOException e) {
            throw new RuntimeException(e);
         }
      }
      if (s.equals("File uploaded successfully!") && songMapper.insert(song) > 0) {
         return Result.success("上传成功", storeUrlPath);
      } else {
         return Result.error("上传失败");
      }
   }

   @Override
   public Result updateSongMsg(SongRequest updateSongRequest) {
      Song song = new Song();
      BeanUtils.copyProperties(updateSongRequest, song);
      if (songMapper.updateById(song) > 0) {
         return Result.success("修改成功");
      } else {
         return Result.error("修改失败");
      }
   }

   @Override
   public Result updateSongUrl(MultipartFile urlFile, int id) {
      Song song = songMapper.selectById(id);
      String path = song.getUrl();
      String[] parts = path.split("/");
      String fileName = parts[parts.length - 1];

      RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder()
              .bucket(bucketName)
              .object(fileName)
              .build();
      fileName = urlFile.getOriginalFilename();
      String s = MinioUploadController.uploadFile(urlFile);
      try {
         minioClient.removeObject(removeObjectArgs);
      } catch (ErrorResponseException e) {
         throw new RuntimeException(e);
      } catch (InsufficientDataException e) {
         throw new RuntimeException(e);
      } catch (InternalException e) {
         throw new RuntimeException(e);
      } catch (InvalidKeyException e) {
         throw new RuntimeException(e);
      } catch (InvalidResponseException e) {
         throw new RuntimeException(e);
      } catch (IOException e) {
         throw new RuntimeException(e);
      } catch (NoSuchAlgorithmException e) {
         throw new RuntimeException(e);
      } catch (ServerException e) {
         throw new RuntimeException(e);
      } catch (XmlParserException e) {
         throw new RuntimeException(e);
      }
      String storeUrlPath = "/" + bucketName + "/" + fileName;
      song.setId(id);
      song.setUrl(storeUrlPath);
      song.setName(fileName);
      if (s.equals("File uploaded successfully!") && songMapper.updateById(song) > 0) {
         return Result.success("更新成功", storeUrlPath);
      } else {
         return Result.error("更新失败");
      }
   }

   /**
    * 更新歌曲图片
    *
    * @param urlFile
    * @param id
    * @return
    */
   @Override
   public Result updateSongPic(MultipartFile urlFile, int id) {
      String fileName = urlFile.getOriginalFilename();
      String storeUrlPath = "/img/singerPic/" + fileName;
      MinioUploadController.uploadSongImgFile(urlFile);
      Song song = new Song();
      song.setId(id);
      song.setPic(storeUrlPath);
      if (songMapper.updateById(song) > 0) {
         return Result.success("上传成功", storeUrlPath);
      } else {
         return Result.error("上传失败");
      }
   }

   @Override
   public Result deleteSong(Integer id) {
      Song song = songMapper.selectById(id);
      String path = song.getUrl();
      String[] parts = path.split("/");
      String fileName = parts[parts.length - 1];
      System.out.println(fileName);
      RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder()
              .bucket(bucketName)
              .object(fileName)
              .build();
      if (songMapper.deleteById(id) > 0) {
         try {
            minioClient.removeObject(removeObjectArgs);
         } catch (ErrorResponseException e) {
            throw new RuntimeException(e);
         } catch (InsufficientDataException e) {
            throw new RuntimeException(e);
         } catch (InternalException e) {
            throw new RuntimeException(e);
         } catch (InvalidKeyException e) {
            throw new RuntimeException(e);
         } catch (InvalidResponseException e) {
            throw new RuntimeException(e);
         } catch (IOException e) {
            throw new RuntimeException(e);
         } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
         } catch (ServerException e) {
            throw new RuntimeException(e);
         } catch (XmlParserException e) {
            throw new RuntimeException(e);
         }
         return Result.success("删除成功");
      } else {
         return Result.error("删除失败");
      }
   }

   @Override
   public Result songOfSingerId(Integer singerId) {
      QueryWrapper<Song> queryWrapper = new QueryWrapper<>();
      queryWrapper.eq("singer_id", singerId);
      return Result.success(null, songMapper.selectList(queryWrapper));
   }

   @Override
   public Result songOfId(Integer id) {
      QueryWrapper<Song> queryWrapper = new QueryWrapper<>();
      queryWrapper.eq("id", id);
      return Result.success(null, songMapper.selectList(queryWrapper));
   }

   @Override
   public Result songOfSingerName(String name) {
      QueryWrapper<Song> queryWrapper = new QueryWrapper<>();
      queryWrapper.like("name", name);
      List<Song> songs = songMapper.selectList(queryWrapper);
      if (songs.isEmpty()) {
         return Result.error("添加失败，没有找到该歌,无法加入该歌单");
      }

      return Result.success(null, songMapper.selectList(queryWrapper));
   }

   @Override
   public Result updateSongLrc(MultipartFile lrcFile, int id) {
      Song song = songMapper.selectById(id);
      if (lrcFile != null && !(song.getLyric().equals("[00:00:00]暂无歌词"))) {
         byte[] fileContent = new byte[0];
         try {
            fileContent = lrcFile.getBytes();
            String content = new String(fileContent, "GB2312");
            song.setLyric(content);
         } catch (IOException e) {
            throw new RuntimeException(e);
         }
      }
      if (songMapper.updateById(song) > 0) {
         return Result.success("更新成功");
      } else {
         return Result.error("更新失败");
      }
   }
}
